import Dep from './Dep'
let uid = 0
export default class Watcher {
  constructor(target, expression, callback) {
    this.id = uid++
    this.target = target
    this.getter = parsePath(expression) // 返回一个函数
    this.callback = callback
    this.value = this.get()
    // console.log(parsePath(expression))
  }
  update() {
    this.run()
  }
  get() {
    Dep.target = this
    const obj = this.target
    var value
    try {
      value = this.getter(obj) // 这里会触发属性的get方法 get方法中
    } finally {
      Dep.target = null
    }
    return value
  }
  run() {
    this.getAndInvoke(this.callback)
  }
  getAndInvoke(cb) {
    const value = this.get()
    if (value !== this.value || typeof value === 'object') {
      const oldVal = this.value
      this.value = value
      cb.call(this.target, value, oldVal)
    }
  }
}
function parsePath(path) {
  const segments = path.split('.')
  return function (obj) {
    for (let i = 0; i < segments.length; i++) {
      if (!obj) return
      obj = obj[segments[i]]
    }
    return obj
  }
}
